Skip to content

fix(ui): give the full player's keys to the PodNotes view's own scope - #469

Merged
chhoumann merged 6 commits into
masterfrom
fix/player-scope-keys
Oct 14, 2026
Merged

chhoumann merged 6 commits into
masterfrom
fix/player-scope-keys

Conversation

@chhoumann

@chhoumann chhoumann commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Why

While the full player was open, a note never got Enter or Escape. In its find bar, Enter didn't move to the next match and Escape didn't close the bar. The player pushed its own key scope onto Obsidian's keymap stack, above the workspace scope that hands keys to the active note. This came in with the v3 shell (#434) and is not released yet.

Fixes #467

What changed

  • The player registers Escape and Space on the PodNotes view's own scope (ItemView.scope). Obsidian hands that scope the keys typed while the view's leaf is active, and focus or a press in the view makes it active. A note, its find bar and every other view get their own keys again.
  • The window-following push and pop of a scope is gone. Inside the view, the keys work as before: Space plays and pauses, except on a control; Escape closes a menu or modal first, then the volume slider, then collapses the player. A queue drag still cancels on Escape.
  • Capture Undo now refuses unless every open editor of the note holds the text as the capture left it. Before, it checked only the first editor it found (a V-466c follow-up).

Scope

  • The test mocks now model Obsidian's workspace scope, which hands each key to the active leaf's view scope, so unit tests exercise the same rule as Obsidian. A test pins that the view's own scope is the one its components register on.
  • No data.json, public API or URI change.

Blast Radius

Every user with the full player open gets their note keys back. The player's own keys now need the PodNotes view to be the active leaf, which any click or focus in the view gives it. A player opened from a link or command while the user types in a note leaves the keys with the note, as #467 asks. In a popout window, Obsidian makes the view's leaf active a moment after the window gets OS focus (it waits about 100 ms), so a key typed in that first moment still goes to the leaf that was active before. The verifier saw this on Linux; macOS and Windows are not checked.

Verification

  • Reproduced first on master in Obsidian 1.14.4 through the isolated runner. With the full player open, Ctrl+F in a note, then Enter, kept the find bar at "1 / 3", and Escape left it open. With the player collapsed, the same keys moved to "2 / 3" and closed the bar.
  • New journey "The open full player swallows Enter and Escape in notes #467 keys typed in a note reach it while the full player is open" fails on master (Enter stays at "1 / 3") and passes here. The Escape-order and Space journeys pass. The new unit test that sends Enter and Escape to a note's own scope fails on master (the note gets no keys) and passes here. The two-pane Undo test fails on master's capture code and passes here.
  • A plain note and a new tab, whose views have no use for Escape or Space, leave the player alone. A unit case for each and the journey "The open full player swallows Enter and Escape in notes #467 Space and Escape typed in a plain note or a new tab leave the full player open and paused" check this with trusted input: Space types in the note, and the player stays open and paused. With the player's keys moved to app.scope, the note case fails on Escape, the new-tab case fails on Space, and the journey fails. All pass here.
  • Journey J-TS-20 presses Undo in the same moment a second pane of the note changes. Undo refuses, and both panes and the file keep the late edit. With the every-editor check removed, it fails.
  • The Escape-order journey failed now and then, here and on master. Obsidian's menu takes the keys in a timer a moment after it shows, and the journey pressed Escape as soon as the menu showed. When Escape won that race, the view under the menu got it, so the volume slider closed and the menu stayed open. Delaying that timer reproduces the failure every time (3 of 3). The journey now waits until the menu holds the keys, and passes with the delay (3 of 3). No user is fast enough to hit this.
  • lint, format:check, typecheck, build, test (svelte-check 0 errors and 0 warnings; 2,528 unit tests), test:tooling (13) and docs:build pass. test:e2e passes 169 of 169 on a fresh vault in Obsidian 1.14.4 (Linux), on master 7642765 merged in.
  • Two reviewers, claude-fable-5-1 and gpt-6-astra, reviewed the change. gpt-6-astra found nothing. claude-fable-5-1's findings on tests, comments and a shared e2e hotkey helper are applied here.
  • Size: 98,075 gzip against master 7642765's 98,183 (-108). Before the merge of feat(ui): rebuild searchable settings and add headset mappings #468, against 35461cd: -130, of which the key-scope fix is -146, from deleting the push and pop code, and the Undo check is +17.

Docs at release

  • podcasts.md, the player section: the player's keys (Space, Escape) work while focus is in the PodNotes view.

Note

Move full-player keyboard handling to PodcastView's own scope

The full player no longer pushes its own Obsidian Scope onto each window's key stack. Instead, MainView.mountPodcastView in index.ts creates a child scope of the app scope, stores it on the view, and passes it through the new required scope field on ShellServices in context.ts.

  • Player.svelte registers Escape and Space on the supplied scope and unregisters them on cleanup, so keys routed to another active leaf no longer collapse the player or toggle playback.
  • Capture Undo in CaptureService.ts now checks all open editors of a note, and refuses to revert when any editor buffer differs from the capture result.
  • Adds unit, integration, and E2E coverage for scope routing, two-pane capture Undo refusal, and note find-bar shortcuts while the player is open. The Obsidian mocks in obsidian.ts now route keys through the active leaf's scope.
  • Risk: ShellServices gained a required scope property, so any code constructing these services without a scope will fail; capture Undo previously reverted via the first matching editor and now reverts only when every open editor matches the capture snapshot.

Macroscope summarized 852f37e.

The full player pushed a key scope above Obsidian's workspace scope, so
while it was open a note never got Enter or Escape, as in its find bar.

The player now registers Escape and Space on the PodNotes view's own scope.
Obsidian hands a view's scope the keys typed while that view's leaf is
active, which focus or a press in the view makes it. A menu or modal over
the player still takes Escape first, and a queue drag still cancels on
Escape.

size: 98,781 gzip (-146 vs master 35461cd 98,927)
With a note open in two panes, Undo checked only the first editor it found.
It now leaves the note unless every open editor of it holds the text as the
capture left it.

size: 98,798 gzip (-129 vs master 35461cd 98,927)
Tests now pin that the view's own scope is the one its components register
on, drop the scaffolding for the removed window-focus path, set the active
leaf through one helper, and press hotkeys through one e2e helper. Undo's
editor check gets a typed list and a test for two matching editors.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Deploying podnotes with  Cloudflare Pages  Cloudflare Pages

Latest commit: 852f37e
Status: ✅  Deploy successful!
Preview URL: https://e7ad3a6d.podnotes.pages.dev
Branch Preview URL: https://fix-player-scope-keys.podnotes.pages.dev

View logs

…across two panes

The note-key tests used a find bar, whose scope consumes Escape, so player
keys registered on app.scope passed both suites. A plain note's editor and
a new tab have no use for Escape or Space: the unit cases and a trusted-input
journey now check that both leave the full player open and paused.

J-TS-20 presses Undo in the same moment a second pane of the note changes,
which the every-editor check refuses.
Obsidian's menu pushes its key scope in a timer after it shows, and CDP input
runs before that timer. An Escape sent as soon as the menu showed could reach
the view under it, which closed the volume slider and left the menu open.
@chhoumann
chhoumann merged commit 400e372 into master Oct 14, 2026
17 checks passed
@chhoumann
chhoumann deleted the fix/player-scope-keys branch October 14, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The open full player swallows Enter and Escape in notes

1 participant